package com.demo.demo;

import ch.qos.logback.core.joran.util.beans.BeanUtil;
import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.ttl.TransmittableThreadLocal;
import com.alibaba.ttl.threadpool.TtlExecutors;
import com.demo.domain.FileRequestEntity;
import com.util.config.HttpUtil;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import okhttp3.HttpUrl;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.MDC;
import org.springframework.http.HttpEntity;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * Copyright
 *
 * @Author WuHuang
 * @Date 2023/3/1
 */
public class Tests {

//    @Resource(name = "threadPoolTaskExecutor")
//    private ThreadPoolTaskExecutor executor;

    public static void main(String[] args) throws Exception {

        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setMaxPoolSize(20);
        executor.setCorePoolSize(10);
        executor.setQueueCapacity(100);
        executor.setKeepAliveSeconds(10);
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());


        int batchLatchCount = 5;
        int indexPage = 1;
        int splitSize = (102 - 1) / batchLatchCount;
        int residueCount = (102 - 1) % batchLatchCount;
        System.out.println(splitSize);
        System.out.println(residueCount);

        List<FileRequestEntity> fileRequestEntities = new ArrayList<>();
        for (int i = 0; i < batchLatchCount; i++) {
            // 深度拷贝
            FileRequestEntity fileRequestEntityDup = new FileRequestEntity();
            JSONObject jsonObject = new JSONObject();
            indexPage = i * splitSize + 2;
            int endPage = (batchLatchCount - 1) == i ? indexPage + splitSize + residueCount - 1 : indexPage + splitSize - 1;
            fileRequestEntityDup.setIndexPage(indexPage);
            fileRequestEntityDup.setEndPage(endPage);
            System.out.println( String.format("获取的数据分段的起始页：homePage:{%s}, 末页: endPage:{%s}, 分段号: batchCount:{%s}", indexPage, endPage, i));
            jsonObject.put("page", fileRequestEntityDup.getIndexPage());
            fileRequestEntityDup.setBody(jsonObject);
            fileRequestEntities.add(fileRequestEntityDup);
        }


        TransmittableThreadLocal<String> context = new TransmittableThreadLocal<>();
        // 在父线程中设置 sessionId
        context.set(MDC.get("tl"));

        CompletableFuture<?>[] cfArr = fileRequestEntities.stream().
                map(entity -> CompletableFuture
                        .supplyAsync(() -> {
                            MDC.put("tl", context.get());
                            for (int i = entity.getIndexPage(); i <= entity.getEndPage(); i++) {
                                try {
                                    // 调用三方拉取数据
                                    entity.getBody().put("page", i);
                                    System.out.println(entity);
//                                    FileDataEntity fileDataEntityDup = downloadDataApi.getDataByPost(entity);
//                                    log.info("执行的 indexPage:{}", i);
                                    System.out.println(String.format("执行的 indexPage:{}", i));
//                                    data.addAll(fileDataEntityDup.getList());
                                } catch (Exception e) {
                                    System.out.println(String.format("请求数据出错-message:{}",e.getMessage()));
                                }
                            }
                            return entity;
                        }, TtlExecutors.getTtlExecutor(executor)).whenComplete((result, throwable) -> {
                            // TODO 执行记录进度条
                        })).toArray(CompletableFuture<?>[]::new);
        // 开始等待所有任务执行完成
        System.out.println(String.format("开始等待所有任务执行完成, 指定并行数：{}", batchLatchCount));
        CompletableFuture.allOf(cfArr).join();
    }


}
